﻿using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Web.Script.Services;
using System.Web.Services;
using System.Xml;

namespace Viby
{
    /// <summary>
    /// Summary description for VibyService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class VibyService : System.Web.Services.WebService
    {
        public string GetWeather(string location)
        {
            WebClient wc = new WebClient();
            byte[] data = wc.DownloadData("http://www.google.com/ig/api?weather=" + location + "&hl=en");
            MemoryStream ms = new MemoryStream(data);
            XmlDocument xml = new XmlDocument();
            xml.Load(ms);
            if (xml.SelectNodes("/xml_api_reply/weather/problem_cause").Count != 1)
            {

                int temperature;
                int.TryParse(xml.SelectNodes("/xml_api_reply/weather/current_conditions/temp_c").Item(0).Attributes[0].Value, out temperature);
                string wind = xml.SelectNodes("/xml_api_reply/weather/current_conditions/wind_condition").Item(0).Attributes[0].Value;
                string sky = xml.SelectNodes("/xml_api_reply/weather/current_conditions/condition").Item(0).Attributes[0].Value;
                location = xml.SelectNodes("/xml_api_reply/weather/forecast_information/city").Item(0).Attributes[0].Value;

                XmlDocument weather = new XmlDocument();
                weather.Load(Server.MapPath("~/App_Data/weatherConditions.xml"));
                XmlNodeList conditions = weather.GetElementsByTagName("condition");
                string recom = "";
                string recom2 = "";
                foreach (XmlNode cond in conditions)
                {
                    if (cond["element"] != null)
                    {
                        string skies = cond["element"].InnerText;
                        if (sky.Equals(skies))
                        {
                            recom2 = cond.ChildNodes[new System.Random().Next(cond.ChildNodes.Count - 1) + 1].InnerText;
                            break;
                        }
                    }
                    else
                    {
                        int from, to;
                        int.TryParse(cond["from"].InnerText, out from);
                        int.TryParse(cond["to"].InnerText, out to);

                        if (temperature >= from && temperature < to)
                        {
                            recom = cond.ChildNodes[new System.Random().Next(cond.ChildNodes.Count - 2) + 2].InnerText;
                        }
                    }
                
                }
                string condition = "";
                if (temperature < 5)
                {
                    condition = "cold";
                }
                else
                {
                    condition = "hot";
                }
                return ServerResponse.Get("weather", new string[]{"It's <b>" + temperature + "</b> degrees to Celcius in " + location + "! <br />" + wind.ToString() + ". <br />" + recom + " <br />" + recom2, condition});
            }else{
                return ServerResponse.Get("weather", new string[]{"Sorry, no weather for such place found <br />"});
            }
        }

        [WebMethod(EnableSession = true)]
        [ScriptMethod(UseHttpGet = true)]
        public string Get(string usertext)
        {
            if (Session != null)
            {
                //return Session.ToString();
            }
            if (usertext.StartsWith("weather", true, CultureInfo.InvariantCulture))
            {
                return GetWeather(usertext.Substring(usertext.IndexOf(' ') + 1));
            }
            if (usertext.StartsWith("ill", true, CultureInfo.InvariantCulture))
            {
                Session.Remove("symptoms");
                Session.Remove("nosymptoms");
                Session["symptoms"] = new List<string>();
                Session["nosymptoms"] = new List<string>();
                return AskForSymptom();
            }
            if (usertext.StartsWith("getillnessinfo", true, CultureInfo.InvariantCulture))
            {
                string symptom = usertext.Substring(usertext.IndexOf(' ') + 1);
                return GetIllnessInfo(symptom);
            }

            object fevermode = Session["fevermode"];
            if (fevermode != null && (bool)fevermode)
            {
                string param = usertext.Substring(usertext.IndexOf(' ') + 1);
                if (param.Equals("yes", System.StringComparison.InvariantCultureIgnoreCase))
                {
                    IllnessResult(true);
                    return AskForSymptom();
                }
                else if (param.Equals("no", System.StringComparison.InvariantCultureIgnoreCase))
                {
                    IllnessResult(false);
                    return AskForSymptom();
                }
            }

            return "I don't understand!";
        }

        public void IllnessResult(bool hasIllness)
        {
            string sympt = Session["symptom_current"] as string;
            List<string> symptoms;
            if (hasIllness)
            {
                symptoms = Session["symptoms"] as List<string>;
            }
            else
            {
                symptoms = Session["nosymptoms"] as List<string>;
            }
            symptoms.Add(sympt);
        }

        public string GetIllnessInfo(string illness)
        {
            XmlDocument health = new XmlDocument();
            health.Load(Server.MapPath("~/App_Data/illness.xml"));
            string[] parameters = new string[4];
            
            XmlNodeList illnesses = health.GetElementsByTagName("illness");
            foreach (XmlNode illnessNode in illnesses)
            {
                string name = illnessNode.SelectSingleNode("name").InnerText;
                if (illness.Equals(name))
                {
                    parameters[0] = name;
                    parameters[1] = illnessNode.SelectSingleNode("symptoms").InnerText; ;
                    parameters[2] = illnessNode.SelectSingleNode("treatment").InnerText; ;
                    parameters[3] = illnessNode.SelectSingleNode("precaution").InnerText; ;
                    break;
                }
            }

            return ServerResponse.Get("illnessinfo", parameters);
        }

        public string AskForSymptom()
        {
            XmlDocument health = new XmlDocument();
            health.Load(Server.MapPath("~/App_Data/illness.xml"));
	        Dictionary<string, int> map = new Dictionary<string,int>();

            List<string> sessionSymptoms = Session["symptoms"] as List<string>;
            List<string> sessionNoSymptoms = Session["nosymptoms"] as List<string>;

            XmlNodeList illnesses = health.GetElementsByTagName("illness");
	        foreach(XmlNode illness in illnesses) {
                XmlNodeList symptoms = illness.SelectNodes("symptom");
		        foreach(XmlNode symptom in symptoms) {
			        string symptomStr = symptom.InnerText;

                    if (sessionSymptoms.Contains(symptomStr) ||
                        sessionNoSymptoms.Contains(symptomStr))
                    {
                        continue;
                    }

			        if (map.ContainsKey(symptomStr)) {
				        map[symptomStr]++;
			        } else {
				        map[symptomStr] = 1;
			        }
		        }
	        }

	        int maximum = 0;
	        string sympt = null;
	        foreach(string symptom in map.Keys){
                int count = map[symptom];
		        if (count > maximum) {
			        maximum = count;
			        sympt = symptom;
		        }
	        }

            Session["fevermode"] = true;
            Session["symptom_current"] = sympt;

            
            List<string> illnessesResult = new List<string>();

            foreach (XmlNode illness in illnesses)
            {
                XmlNodeList symptoms = illness.SelectNodes("symptom");
                List<string> matchSymptoms = new List<string>(sessionSymptoms);
                bool includeIllness = true;
                foreach (XmlNode symptom in symptoms)
                {
                    string symptomStr = symptom.InnerText;

                    if (sessionSymptoms.Contains(symptomStr)) {
                        matchSymptoms.Remove(symptomStr);
                    } else if (sessionNoSymptoms.Contains(symptomStr)) {
                        includeIllness = false;
                        break;
                    }
                }
                if (includeIllness && matchSymptoms.Count == 0)
                {
                    string illnessStr = illness["name"].InnerText;
                    illnessesResult.Add(illnessStr);
                }
            }

            if (illnessesResult.Count <= 7)
            {
                return ServerResponse.Get("illresults", illnessesResult.ToArray());
            }
            
            return ServerResponse.Get("asksymptom", "Do you have this symptom: " + sympt + "?");
        }
    }
}
